package cz.bernhard.playground.persistance.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.sql.DataSource;

import net.sf.log4jdbc.ConnectionSpy;
import net.sf.log4jdbc.DriverSpy;

import org.apache.commons.lang.RandomStringUtils;

import com.google.common.collect.Lists;
import com.mysql.jdbc.Driver;

import cz.bernhard.playground.persistance.domain.Contact;
import cz.bernhard.playground.persistance.domain.User;

public class UserDaoPureJdbcImpl implements UserDao {
	
	private DataSource dataSource;

	


	public UserDaoPureJdbcImpl() {
		// TODO Auto-generated constructor stub
	}
	

	public List<User> findAll() {

		
		Connection conn = null;
		Statement st = null;
		try {
			conn = getConnection();
			st = conn.createStatement();
			
			ResultSet rs = st.executeQuery("select * from tusers");
			
			List<User> users = Lists.newArrayList();
			while(rs.next() == true) {
				User user = new User();

				user.setId(rs.getLong("uid"));
				user.setUsername(rs.getString("username"));

				Contact contact = new Contact();
				user.setContact(contact);

				contact.setFirstName(parseFirstNameFromFullName(rs.getString("name")));
				contact.setSecondName(parseSecondNameFromFullName(rs.getString("name")));
				contact.setPhone(rs.getString("phone"));
				contact.setAddress(rs.getString("address"));
				contact.setZipcode(rs.getString("zipcode"));
				contact.setCity(rs.getString("city"));
				
				users.add(user);
			}
			
			return users;
			
		} catch (SQLException e) {
			throw new RuntimeException(e);
		} 
		catch (Exception e) {
			throw new RuntimeException(e);
		}
		finally {
			try {
				if (st != null)	st.close();
				if (conn != null) conn.close();
			} catch (Exception e) {
				throw new RuntimeException(e);
			} 
		}
		
	}

	public User findById(Long id) {
		// TODO Auto-generated method stub
		return null;
	}

	public User deleteById(Long id) {
		// TODO Auto-generated method stub
		return null;
	}
	
	public boolean matchPassword(User user) {
		
		Connection conn = null;
		Statement st = null;
		try {
			conn = getConnection();
			st = conn.createStatement();
			ResultSet rs = st.executeQuery(
					"select count(*) from tusers where username='" + user.getUsername() + "' AND " +
					"password='" + user.getPassword() + "';"
					);
			rs.next();
			int count = rs.getInt(1); //count
			return count > 0;
		} catch (SQLException e) {
			throw new RuntimeException(e);
		} 
		catch (Exception e) {
			throw new RuntimeException(e);
		}
		finally {
			try {
				if (st != null)	st.close();
				conn.close();
			} catch (Exception e) {
				throw new RuntimeException(e);
			} 
		}
		
	}

	public Long save(User user) {
		Connection conn = null;
		PreparedStatement st = null;
		
		try {
			conn = getConnection();
						
			st = conn.prepareStatement(
					"INSERT INTO TUSERS(username, password, name, address, zipcode, city, phone) " +
					"VALUES (?, ?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS);
					
			st.setString(1, user.getUsername() +"_" + RandomStringUtils.randomAlphanumeric(8));
			st.setString(2, user.getPassword());
			Contact contact = user.getContact();
			st.setString(3, contact.getFullName());
			st.setString(4, contact.getAddress());
			st.setString(5, contact.getZipcode());
			st.setString(6, contact.getCity());
			st.setString(7, contact.getPhone());
			
			st.execute();
			ResultSet rs = st.getGeneratedKeys();
			rs.next();
			return rs.getLong(1);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		} 
		catch (Exception e) {
			throw new RuntimeException(e);
		}
		finally {
			try {
				if (st != null)	st.close();
				if (conn != null) conn.close();
			} catch (Exception e) {
				throw new RuntimeException(e);
			} 
		}
	}
	
	

	private Connection getConnection() throws Exception {
		return getDataSource().getConnection();
	}


	private String parseFirstNameFromFullName(String fullName) {
		Pattern pattern = Pattern.compile("([a-zA-Z]*)\\s*([a-zA-Z]*)");
		Matcher matcher = pattern.matcher(fullName);
		matcher.matches();
		return matcher.group(1);
	}
	
	private String parseSecondNameFromFullName(String fullName) {
		Pattern pattern = Pattern.compile("([a-zA-Z]*)\\s*([a-zA-Z]*)");
		Matcher matcher = pattern.matcher(fullName);
		matcher.matches();
		return matcher.group(2);
	}


	public DataSource getDataSource() {
		return dataSource;
	}


	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}

	
	
	
	

}
